#include "GameObject.h"

GameObject::GameObject()
{
}
GameObject::GameObject(LPDIRECT3DDEVICE9 pD3DDevice, char* fileName, D3DXVECTOR3 newPosition, D3DXVECTOR3 newRotation, D3DXVECTOR3 newScale)
{
		position = newPosition;
		rotation = newRotation;
		scale = newScale;

		LPD3DXBUFFER pD3DXMtrlBuffer;
		g_pd3dDevice = pD3DDevice;	
    // Load the mesh from the specified file

    if( FAILED( D3DXLoadMeshFromX( fileName, D3DXMESH_SYSTEMMEM, 
                                   g_pd3dDevice, NULL, 
                                   &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, 
                                   &g_pMesh ) ) )
    {      
            MessageBox(NULL, fileName, "Meshes.exe", MB_OK);                  
    }

    // We need to extract the material properties and texture names from the 
    // pD3DXMtrlBuffer
    D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
    g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];    
    g_pMeshTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];      

    for( DWORD i=0; i<g_dwNumMaterials; i++ )
    {
        // Copy the material
        g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;

        // Set the ambient color for the material (D3DX does not do this)
        g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;

        g_pMeshTextures[i] = NULL;
        if( d3dxMaterials[i].pTextureFilename != NULL && 
            lstrlenA(d3dxMaterials[i].pTextureFilename) > 0 )
        {
            // Create the texture
            if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, 
                                                d3dxMaterials[i].pTextureFilename, 
                                                &g_pMeshTextures[i] ) ) )
            {
                // If texture is not in current folder, try parent folder
                const CHAR* strPrefix = "..\\";
                CHAR strTexture[MAX_PATH];
                StringCchCopyA( strTexture, MAX_PATH, strPrefix );
                StringCchCatA( strTexture, MAX_PATH, d3dxMaterials[i].pTextureFilename );
                // If texture is not in current folder, try parent folder
                if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, 
                                                    strTexture, 
                                                    &g_pMeshTextures[i] ) ) )
                {
                    MessageBox(NULL, "Could not find texture map", "Meshes.exe", MB_OK);
                }
            }
        }
    }

    // Done with the material buffer
    pD3DXMtrlBuffer->Release();
    
}

GameObject::~GameObject(void)
{
	  if( g_pMeshMaterials != NULL ) 
        delete[] g_pMeshMaterials;

    if( g_pMeshTextures )
    {
        for( DWORD i = 0; i < g_dwNumMaterials; i++ )
        {
            if( g_pMeshTextures[i] )
                g_pMeshTextures[i]->Release();
        }
        delete[] g_pMeshTextures;
    }
    if( g_pMesh != NULL )
        g_pMesh->Release();
}

void GameObject::Render(void)
{
	  // Meshes are divided into subsets, one for each material. Render them in
        // a loop
	    D3DXMATRIXA16 matWorld;
		D3DXMATRIXA16 tmp;

		D3DXMatrixIdentity(&matWorld);
		D3DXMatrixScaling(&tmp,scale.x,scale.y,scale.z);
		matWorld *= tmp;
			
		D3DXMatrixRotationX(&tmp,rotation.x);
		matWorld *= tmp;
		D3DXMatrixRotationY(&tmp,rotation.y);
		matWorld *= tmp;
		D3DXMatrixRotationZ(&tmp,rotation.z);
		matWorld *= tmp;

		D3DXMatrixTranslation(&tmp,position.x,position.y,position.z);
		matWorld *= tmp;
		g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
		
        for( DWORD i=0; i<g_dwNumMaterials; i++ )
        {
            // Set the material and texture for this subset
			
            g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
            g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
        
            // Draw the mesh subset
            g_pMesh->DrawSubset( i );
        }
}